
/*
 * Copyright (C) Zhu Jiashun
 * Copyright (C) Zaver
 */

#ifndef ZV_LIST_H
#define ZV_LIST_H

#ifndef NULL
#define NULL 0
#endif

/*
* list_head, reference linux kernel implementation 参考 Linux 内核实现
*/

struct list_head
{
    struct list_head *prev, *next; // 前、后节点
};

typedef struct list_head list_head;

// 初始化一个 list，prev 和 next 都是自己
#define INIT_LIST_HEAD(ptr)                               \
    do                                                    \
    {                                                     \
        struct list_head *_ptr = (struct list_head *)ptr; \
        (_ptr)->next = (_ptr);                            \
        (_ptr->prev) = (_ptr);                            \
    } while (0)

/*
* Insert a new entry to two consecutive entries. 在 prev 和 next 中插入 new
*/
static inline void __list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
{
    _new->next = next;
    next->prev = _new;
    prev->next = _new;
    _new->prev = prev;
}

static inline void list_add(struct list_head *_new, struct list_head *head)
{
    __list_add(_new, head, head->next); // 向前面增加
}

static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
    __list_add(_new, head->prev, head); // 向后面新增
}

/*
* Delete a entry to two consecutive entries.
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
    prev->next = next;
    next->prev = prev;
}

static inline void list_del(struct list_head *entry)
{
    __list_del(entry->prev, entry->next); // 删除节点
    //entry->next = entry->prev = NULL;
}

/*
*   check whether the list is empty 链表是否为空
*/
static inline int list_empty(struct list_head *head)
{
    return (head->next == head) && (head->prev == head);
}

// 得到 field 在结构体中的偏移量
#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)

// 先得到结构体中 member 字段的类型
// 然后减去 member 在结构体中的偏移
// 得到结构体的地址，然后转化为指针
#define container_of(ptr, type, member) ({             \
    const typeof(((type *)0)->member) *__mptr = (ptr); \ 
    (type *)((char *)__mptr - offsetof(type, member)); \
})

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

// 链表向后遍历
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

// 链表向前遍历
#define list_for_each_prev(pos, head) \
    for (pos = (head)->prev; pos != (head); pos = pos->prev)

/*
#define list_for_each_entry(pos, head, member)  \
    for (pos = list_entry((head)->next, typeof(*pos), member);  \
        &(pos->member) != (head);                               \
        pos = list_entry(pos->member.next, typeof(*pos), member))
*/

#endif
